# Copyright 2009 http://www.yuntien.com
# Licensed under the Apache License, Version 2.0

import os, datetime, urllib
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

from ytblog.model.blog import *
from ytblog.model.tag import *
from ytblog.helper.decorators import *
import ytblog.config
import ytblog.model.authorization as authorization
from ytblog.plugin import *

class BlogController(webapp.RequestHandler):

  def add_common_context(self, context):
    self.add_user(context)
    self.add_lang(context)
    self.add_config(context)
    self.add_tags(context)
    self.add_plugins(context)
    self.add_template_tags()
    
  def add_user(self, context):
    context['user'] = users.get_current_user()
    context['admin'] = users.is_current_user_admin()
    
    if context['user']:
      context['url'] = users.create_logout_url(self.request.url)
    else:
      context['url'] = users.create_login_url(self.request.url)
      
    context['auth'] = authorization.get_auth((Blog, None))
    context['auth_comment'] = authorization.get_auth((Comment, None))

  def add_lang(self, context):  
    lang = ytblog.config.LANG
    # override default lang setting
    query = self.request.GET
    if query.has_key('lang'):
      lang = query['lang']

    lang_module_name = 'ytblog.langs.' + lang
    lang_module = __import__(lang_module_name, globals(), locals(), ['LANG'], -1)
    context['lang'] = lang_module.LANG

  def add_config(self, context):
    context['config'] = ytblog.config.CONFIG
    context['ytblog_use_promotion'] = ytblog.config.USE_PROMOTION
    
  def add_tags(self, context):
    tags = TagInfo.get_tags()
    for tag in tags:
      tag.date += datetime.timedelta(hours = ytblog.config.TIMEZONE_OFFSET)
    context['tags'] = tags
    
    context['tag'] = self.request.get('tag', '')
    
  def add_plugins(self, context):
    plugins = [plugin for plugin in PLUGINS if plugin['type'] == TYPE_SIDE]
    context['plugins'] = self.get_plugins_context(plugins)

    plugins = [plugin for plugin in PLUGINS if plugin['type'] == TYPE_TOP]
    context['plugins_top'] = self.get_plugins_context(plugins)

    plugins = [plugin for plugin in PLUGINS if plugin['type'] == TYPE_BOTTOM]
    context['plugins_bottom'] = self.get_plugins_context(plugins)
  
  def add_template_tags(self):
    template.register_template_library('ytblog.templatetags.string')    
    
  def get_plugins_context(self, plugins):
    context = []
    for plugin in plugins:
      plugin_path = 'ytblog.plugin.' + plugin['name']
      plugin_module = __import__(plugin_path, globals(), locals(), ['main'], -1)
      plugin['view_path'] = ytblog.config.PLUGIN_DIR + plugin['name'] + '/' + plugin['view'] 
      context.append({'config':plugin, 'data':plugin_module.main(self.request)})
    
    return context    

  def fill_blog_info(self, blog):
    blog.tag_num = len(blog.tags)
    blog.blog_tag = blog.get_tag_str()
    blog.auth = authorization.get_auth((Blog, blog))
    blog.date += datetime.timedelta(hours = ytblog.config.TIMEZONE_OFFSET)
    blog.update += datetime.timedelta(hours = ytblog.config.TIMEZONE_OFFSET)
    return blog

  def change_query_str(self, name, value):
    get = self.request.str_GET
    get[name] = str(value)
    query_str = urllib.urlencode(get) 
    return self.request.path + '?' + query_str

  def get_page_offset(self, page_qs):
    try:
      page = int(self.request.get(page_qs, 1))
      if page < 1:
        page = 1
    except:
      page = 1
      
    offset = page - 1
    return (page, offset)

  #do pagination
  def get_page_info(self, page_qs, next=False):
    page_num, offset = self.get_page_offset(page_qs)
    page = {}

    if offset > 0:
      page['prev'] = True
      page['prev_page'] = page_num - 1
      page['prev_page_url'] = self.change_query_str(page_qs, page['prev_page'])
    if next == True:
      page['next'] = True
      page['next_page'] = page_num + 1
      page['next_page_url'] = self.change_query_str(page_qs, page['next_page'])

    return page

  def get_page_objects(self, query, num_per_page, page_qs='page'):
    page_num, offset = self.get_page_offset(page_qs)
    objects = query.fetch(num_per_page+1, num_per_page*offset)
    #pagination info
    page = self.get_page_info(page_qs, len(objects) > num_per_page)
    objects = objects[0:num_per_page]
    return (objects, page)
